package first.group.ssh.packet;

import first.group.ssh.SSHConsts;
import first.group.ssh.channel.ChannelRequest;
import first.group.ssh.channel.ChannelRequestParser;
import first.group.ssh.packet.reader.BooleanReader;
import first.group.ssh.packet.reader.IntegerReader;
import first.group.ssh.packet.reader.StringReader;
import first.group.ssh.packet.writer.BooleanWriter;
import first.group.ssh.packet.writer.StringWriter;
import java.io.IOException;
import java.nio.ByteBuffer;

public class ChannelRequestPacket extends Packet{
    public final int recipientChannel;
    public final String requestType;
    public final boolean wantReply;
    public final ChannelRequest request;

    public ChannelRequestPacket(int recipientChannel, String requestType, boolean wantReply, ChannelRequest request) {
        super(SSHConsts.SSH_MSG_CHANNEL_REQUEST);
        this.recipientChannel = recipientChannel;
        this.requestType = requestType;
        this.wantReply = wantReply;
        this.request = request;
    }

    public static PacketParser<ChannelRequestPacket> PARSER = new ChannelRequestPacket.Parser();

    private static class Parser extends PacketParser<ChannelRequestPacket> {

        @Override
        public ChannelRequestPacket parse(ByteBuffer buffer) throws IOException {
            var recipientChannel = IntegerReader.readInteger(buffer);
            if (recipientChannel == null) {
                return null;
            }
            var requestType = StringReader.readString(buffer);
            if (requestType == null) {
                return null;
            }
            var wantReply = BooleanReader.readBoolean(buffer);
            if (wantReply == null) {
                return null;
            }
            ChannelRequest request = null;
            if (ChannelRequestParser.isSupported(requestType)) {
                request = ChannelRequestParser.parse(requestType, buffer);
                if (request == null) {
                    return null;
                }
            }
            return new ChannelRequestPacket(recipientChannel, requestType, wantReply, request);
        }
    }

    @Override
    public void write(ByteBuffer buffer) {
        buffer.putInt(recipientChannel);
        StringWriter.writeString(buffer, requestType);
        BooleanWriter.writeBoolean(buffer, wantReply);
        request.write(buffer);
    }
}
